"""
HiAgent Chat SDK 配置管理模块

提供配置管理功能，支持从环境变量、配置文件等方式加载配置。
"""

import os
from typing import Optional, Dict, Any
from dataclasses import dataclass, field


@dataclass
class HiAgentConfig:
    """HiAgent配置类"""
    
    # API配置
    app_key: str = ""
    base_url: str = "https://api.hiagent.com"
    timeout: int = 30
    max_retries: int = 3
    retry_delay: float = 1.0
    
    # 请求配置
    user_agent: str = "HiAgent-Python-SDK/1.0.0"
    verify_ssl: bool = True
    
    # 日志配置
    log_level: str = "INFO"
    log_format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    
    # 流式响应配置
    stream_chunk_size: int = 1024
    stream_timeout: int = 60
    
    # 其他配置
    default_response_mode: str = "blocking"  # blocking 或 streaming
    default_page_size: int = 20
    
    # 自定义配置
    extra_config: Dict[str, Any] = field(default_factory=dict)
    
    @classmethod
    def from_env(cls, prefix: str = "HIAGENT_") -> "HiAgentConfig":
        """从环境变量创建配置
        
        Args:
            prefix: 环境变量前缀
            
        Returns:
            HiAgentConfig: 配置对象
        """
        config = cls()
        
        # 从环境变量读取配置
        env_mappings = {
            f"{prefix}APP_KEY": "app_key",
            f"{prefix}BASE_URL": "base_url",
            f"{prefix}TIMEOUT": ("timeout", int),
            f"{prefix}MAX_RETRIES": ("max_retries", int),
            f"{prefix}RETRY_DELAY": ("retry_delay", float),
            f"{prefix}USER_AGENT": "user_agent",
            f"{prefix}VERIFY_SSL": ("verify_ssl", lambda x: x.lower() in ('true', '1', 'yes')),
            f"{prefix}LOG_LEVEL": "log_level",
            f"{prefix}LOG_FORMAT": "log_format",
            f"{prefix}STREAM_CHUNK_SIZE": ("stream_chunk_size", int),
            f"{prefix}STREAM_TIMEOUT": ("stream_timeout", int),
            f"{prefix}DEFAULT_RESPONSE_MODE": "default_response_mode",
            f"{prefix}DEFAULT_PAGE_SIZE": ("default_page_size", int),
        }
        
        for env_key, attr_info in env_mappings.items():
            env_value = os.getenv(env_key)
            if env_value is not None:
                if isinstance(attr_info, tuple):
                    attr_name, converter = attr_info
                    try:
                        setattr(config, attr_name, converter(env_value))
                    except (ValueError, TypeError):
                        # 忽略转换错误，使用默认值
                        pass
                else:
                    setattr(config, attr_info, env_value)
        
        return config
    
    @classmethod
    def from_dict(cls, config_dict: Dict[str, Any]) -> "HiAgentConfig":
        """从字典创建配置
        
        Args:
            config_dict: 配置字典
            
        Returns:
            HiAgentConfig: 配置对象
        """
        config = cls()
        
        for key, value in config_dict.items():
            if hasattr(config, key):
                setattr(config, key, value)
            else:
                config.extra_config[key] = value
        
        return config
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典
        
        Returns:
            Dict[str, Any]: 配置字典
        """
        result = {}
        for field_info in self.__dataclass_fields__.values():
            if field_info.name != 'extra_config':
                result[field_info.name] = getattr(self, field_info.name)
        
        # 添加自定义配置
        result.update(self.extra_config)
        
        return result
    
    def validate(self) -> None:
        """验证配置
        
        Raises:
            ValueError: 配置无效时抛出
        """
        if not self.app_key:
            raise ValueError("app_key不能为空")
        
        if not self.base_url:
            raise ValueError("base_url不能为空")
        
        if self.timeout <= 0:
            raise ValueError("timeout必须大于0")
        
        if self.max_retries < 0:
            raise ValueError("max_retries不能小于0")
        
        if self.retry_delay < 0:
            raise ValueError("retry_delay不能小于0")
        
        if self.default_response_mode not in ["blocking", "streaming"]:
            raise ValueError("default_response_mode必须是'blocking'或'streaming'")
        
        if self.default_page_size <= 0:
            raise ValueError("default_page_size必须大于0")


class ConfigManager:
    """配置管理器"""
    
    _instance: Optional["ConfigManager"] = None
    _config: Optional[HiAgentConfig] = None
    
    def __new__(cls) -> "ConfigManager":
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def load_config(self, config: Optional[HiAgentConfig] = None,
                   config_dict: Optional[Dict[str, Any]] = None,
                   from_env: bool = True) -> HiAgentConfig:
        """加载配置
        
        Args:
            config: 配置对象
            config_dict: 配置字典
            from_env: 是否从环境变量加载
            
        Returns:
            HiAgentConfig: 配置对象
        """
        if config is not None:
            self._config = config
        elif config_dict is not None:
            self._config = HiAgentConfig.from_dict(config_dict)
        elif from_env:
            self._config = HiAgentConfig.from_env()
        else:
            self._config = HiAgentConfig()
        
        # 验证配置
        self._config.validate()
        
        return self._config
    
    def get_config(self) -> HiAgentConfig:
        """获取当前配置
        
        Returns:
            HiAgentConfig: 配置对象
            
        Raises:
            RuntimeError: 配置未加载时抛出
        """
        if self._config is None:
            raise RuntimeError("配置未加载，请先调用load_config()")
        
        return self._config
    
    def update_config(self, **kwargs) -> None:
        """更新配置
        
        Args:
            **kwargs: 要更新的配置项
        """
        if self._config is None:
            raise RuntimeError("配置未加载，请先调用load_config()")
        
        for key, value in kwargs.items():
            if hasattr(self._config, key):
                setattr(self._config, key, value)
            else:
                self._config.extra_config[key] = value
        
        # 重新验证配置
        self._config.validate()


# 全局配置管理器实例
config_manager = ConfigManager()


def get_config() -> HiAgentConfig:
    """获取全局配置
    
    Returns:
        HiAgentConfig: 配置对象
    """
    return config_manager.get_config()


def load_config(config: Optional[HiAgentConfig] = None,
               config_dict: Optional[Dict[str, Any]] = None,
               from_env: bool = True) -> HiAgentConfig:
    """加载全局配置
    
    Args:
        config: 配置对象
        config_dict: 配置字典
        from_env: 是否从环境变量加载
        
    Returns:
        HiAgentConfig: 配置对象
    """
    return config_manager.load_config(config, config_dict, from_env)